\section{Fonctionnalités}

Nous avons développés plusieurs fonctionnalités pour notre application. Elles servent principalement d'exemple d'utilisation de tags NFC et d'un téléphone Android, mais certaines servent également à tester la réactivité de l'interaction entre ces deux périphériques.
\subsection{Initialisation}
L'initialisation sert à formater les tags et écrire certaines données précises dessus : 
\begin{itemize}
\item Les coordonnées propres aux tags : indispensable pour l'utilisation d'autres applications.
\item La taille de la matrice : utilisée principalement pour faciliter l'affichage. Elle peut également servir à différencier 2 matrices de tailles différentes.
\item Une valeur : données utiles pour les applications, il est stocké sous la forme d'un \texttt{Object} convertit en \textit{bytes}.
\end{itemize}

Pour initialiser la matrice, l'utilisateur doit écrire sur chacun des tags dans un ordre précis, comme le schéma ci-dessous : 

\begin{figure}[!ht]
\begin{minipage}[c]{.46\linewidth}
\center \includegraphics[scale=0.30]{RESSOURCES/initialisation-tags.png}
\caption{Séquence d'initialisation}
\end{minipage}
\hfill
\begin{minipage}[c]{.46\linewidth}
\center \includegraphics[scale=0.30]{RESSOURCES/screen/init.png}
\caption{Capture d'écran}
\end{minipage}
\end{figure}


\subsection{Paint}
La première application que nous avons développée permet de faire du dessin sur notre table interactive. Elle comporte deux modes : un mode écriture et un mode lecture.\\
\begin{itemize}
\item Dans le mode écriture on peut choisir une couleur sur une palette, puis en plaçant le téléphone sur le tag que l'on veut colorer on lui écrit cette couleur. Le mode écriture possède aussi un outil de prévisualisation pour observer les tags déjà colorés.
\item Le mode lecture permet d'afficher le dessin de la table sur le téléphone. Il suffit de parcourir tous les tags avec le téléphone et l'image s'affiche point par point à chaque lecture de tag. À chaque tag scanné, un pixel de la couleur lue s'affiche sur l'écran. Nous avons choisi de faire des pixels carrés. Leur taille dépend de la dimension de la grille. On ajuste cette taille, de façon à exploiter au mieux l'écran du téléphone.

\begin{figure}[!ht]
\begin{minipage}[c]{.46\linewidth}
\center \includegraphics[scale=0.30]{RESSOURCES/screen/write.png}
\caption{Sélection de la valeur à insérer dans le tag}
\end{minipage}
\hfill
\begin{minipage}[c]{.46\linewidth}
\center \includegraphics[scale=0.30]{RESSOURCES/screen/write2.png}
\caption{Prévisualisation des valeurs écrites sur les tags}
\end{minipage}
\end{figure}


\end{itemize}

\subsection{Lancement d'application}
Nous avons aussi créé une application qui permet d'associer un mouvement (une séquence de tags) au lancement d'une autre application. Ici aussi l'application est composée de plusieurs modes : un mode de création, de lancement et un mode de visualisation.

\paragraph{Gestion de mouvement\\}

Nous avons donné la possibilité à l'utilisateur d'enregistrer ses propres mouvements et d'y associer des actions. À chaque mouvement nous associons une règle composée d'un nom, d'une description, d'une trajectoire (relative ou absolue) et d'une application à lancer en cas de reconnaissance. Chaque règle est stockée dans la base de données de l'application. 
La vue principale permet de lister, d'ajouter de nouvelles règles et de supprimer des règles déjà existantes.
En sélectionnant une règle existante il est possible d'afficher la trajectoire associée.

\paragraph{Utilisation des mouvements\\}

Avant chaque reconnaissance il est important de choisir la nature du mouvement : relative ou absolue, ensuite il suffit d'effectuer la trajectoire tout en maintenant le bouton principal. Une fois l'enregistrement terminé, l'application interroge la base de données pour y rechercher l'action associée. En cas de recherche fructueuse, l'action associée au mouvement est exécutée. Dans le cas contraire, il ne se passe rien.

\begin{figure}[!ht]
\begin{minipage}[c]{.44\linewidth}
\center \includegraphics[scale=0.30]{RESSOURCES/screen/map1.png}
\caption{Création d'un \textit{trigger Google Map}}
\end{minipage}
\hfill
\begin{minipage}[c]{.46\linewidth}
\center \includegraphics[scale=0.30]{RESSOURCES/screen/map2.png}
\caption{Sélection de l'application associée au \textit{trigger}}
\end{minipage}
\end{figure}

Pour gérer le stockage des actions nous avons créé une base de données. Cette base est interrogée lorsque l'on fait des mouvements dans le mode lancement. Elle est aussi mise à jour à chaque ajout et suppression de mouvements ainsi que pour la visualisation des actions.
%enregistrement et détection de mouvements	
%BDD
	
\subsection{Calcul de réactivité}
Le but du projet étant d'avoir une interactivité avec la table NFC, les mouvements avec le téléphone doivent être fait de manière fluide. Pour tester si cela était possible nous avons fait une application de test de performances.\\
Un chronomètre prend des mesures en millisecondes. Il s'arrête a chaque fois que le téléphone détecte un tag, le lit et écrit dessus et le temps mis est affiché.
Vous pourrez trouver les résultats des mesures effectuées dans la partie \ref{Mesures}
% Calcul temps detect/read/write

\subsection{Tic-Tac-Toe}
Le \textit{Tic-Tac-Toe} est un petit jeu de réflexion sur une grille $3*3$. Deux joueurs s'affrontent simultanément. Ils doivent remplir chacun à leur tour une case de la grille avec le symbole qui leur est attribué : O ou X. Le gagnant est celui qui arrive à aligner trois symboles identiques, horizontalement, verticalement ou en diagonale. Ce mode est jouable avec deux téléphones, un par joueur. Après avoir initialisé une grille de tags $3*3$ un joueur place son symbole en passant son téléphone sur le tag approprié. Les deux téléphone communiquant en bluetooth, ils s'envoient au fur et à mesure les coordonnées des symboles que l'on rajoute et peuvent ainsi mettre à jour la visualisation de la partie.


\begin{figure}[!ht]
\begin{minipage}[c]{.46\linewidth}
\center \includegraphics[scale=0.30]{RESSOURCES/screen/toe.png}
\caption{Partie en cours}
\end{minipage}
\hfill
\begin{minipage}[c]{.46\linewidth}
\center \includegraphics[scale=0.30]{RESSOURCES/screen/tac.png}
\caption{Serveur en attente d'adversaire}
\end{minipage}
\end{figure}

Le \textit{Tic-Tac-Toe} n'utilisent pas les mouvements puisque les joueurs scannent chacun leurs tour un tag à la fois. Il ne faisait donc pas partie des objectif principaux du projet. Cependant nous avons souhaité le faire car nous trouvions que l'interaction entre les téléphones associé avec la technologie NFC pouvait être intéressante et cela illustre tout de même les possibilités qu'offrent cette technologie.
\FloatBarrier
\subsection{Labyrinthe}
Nous avons développé un jeu utilisant la technologie NFC associé au mouvement. Le but du jeu étant d'aller du point en bas à gauche de la matrice pour arriver en haut à droite le tout sans utiliser le mauvais chemin sous peine de recommencer au début. La grille de jeu s'adapte en fonction de la matrice utilisée afin de faire la plus grande aire de jeu possible. Nous avons utilisé un algorithme assurant l'existence d'au moins un chemin possible entre le point de départ et le point d'arrivée. Les déplacements autorisées sont uniquement sur les cases adjacentes à la dernière position scannée sinon l'utilisateur est notifié.
\begin{figure}[!ht]
\includegraphics[scale=0.30]{RESSOURCES/screen/labyrinth.png}
\caption{Jeu du labyrinthe sur une matrice $3*3$}
\end{figure}

\newpage

\section{Implémentations}

\subsection{Manifest}

% PERMISSIONS ANDROID MANIFEST
\subsubsection{Permissions de l'application}
Pour permettre l'utilisation de la puce NFC, nous avons du donnée la permission dans le fichier \texttt{AndroidManifest.xml}.
Lorsque l'on a fini de lire ou d'écrire sur un tag, nous avons choisi de faire vibrer le téléphone. Cette fonctionnalité permet de notifier facilement l'utilisateur que l'action sur un tag est terminée.

\lstset{language=java, title=Permissions} 	
\begin{lstlisting}[frame=trBL]
<uses-permission android:name="android.permission.NFC" />
<uses-permission android:name="android.permission.VIBRATE" />
 \end{lstlisting}

% INTENT FILTER
\subsubsection{Intent Filter}
Lorsque l'on passe le téléphone sur un tag, nous le détectons en récupérant l'intent. Il existe trois types d'intent pour le NFC. Ces intents sont obtenus suivant les cas :
\begin{itemize}
\item \texttt{ACTION\_NDEF\_DISCOVERED} lance une activité si un tag contenant des messages de type NDEF est découvert.
\item \texttt{ACTION\_TECH\_DISCOVERED} lance une activité si un tag contenant une technologie spécifique connue est découvert.
\item \texttt{ACTION\_TAG\_DISCOVERED} lance une activité si un tag est découvert et aucun des autres intents n'a été obtenue.
\end{itemize}

\begin{figure}[!ht]
\center \includegraphics[scale=0.6]{RESSOURCES/nfc_tag_dispatch.png}
\caption{Récupération des intents lors de la découverte de tags.}
\end{figure}

\subsection{Gestion du NFC}
% OnNewIntent 
Lors de la détection d'un tag NFC, un des 3 intents précédemment cités est déclenché. La méthode \texttt{onNewIntent} est invoquée à la réception d'un intent, nous vérifions donc le type de l'intent et le traitons. Le traitement est différent selon les cas : lecture seule, lecture écriture ou encore formatage du tag si celui ci est encore vierge.
\\

% Onresume => focus et traitement des intents
Les téléphones demandent quelle application utiliser lors de la découverte d'un tag. Par défaut, le système Android demande quelle est l'application à utiliser lors de la réception d'un intent. Pour empêcher cette demande et forcer notre application à être utilisée lorsque celle-ci est lancée, nous avons surchargé la méthode \texttt{onResume} de chaque activité nécessitant l'utilisation du NFC : \\

\lstset{language=java, title=Gestion du focus NFC} 	
\begin{lstlisting}[frame=trBL]
PendingIntent pendingIntent = PendingIntent.getActivity(act, 0,
				new Intent(act, act.getClass()).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP), 0);
NfcAdapter.getDefaultAdapter(act).enableForegroundDispatch(act,
				pendingIntent, null, null);
\end{lstlisting}
Ces lignes de codes permettent à l'application de garder le focus sur les intents dépendantes du NFC.

\subsection{Lecture et écriture des tags}

% NFCUtil/Payload
Afin de gérer facilement la lecture et l'écriture des tags, nous avons créé une classe \texttt{NFCUtil} possédant les méthodes \texttt{readTagObject} et \texttt{writeTagObject} permettant respectivement la lecture et l'écriture d'un tag à partir d'un Intent. Ces fonctions utilisent l'API Android pour communiquer avec le tag mais fournissent une interface plus agréable pour le développeur. \\
La méthode d'écriture utilise un objet \texttt{PayloadTag} contenant toutes les informations nécessaires aux applications, dont une variable \texttt{value} de type \texttt{Object} laissant au développeur la possibilité de mettre les informations de son choix sur le tag.
\\

\begin{figure}[h]

\begin{center}
\begin{tabular}{p{0.3cm} p{1cm} p{1cm}p{2.2cm}p{2.3cm} p{3.5cm} p{3cm}}
& 0 & 32 & 64 & 96 & 128 & 1024 bits\\
\end{tabular}

\begin{tabular}{|p{1cm}|p{1cm}|p{2.2cm}|p{2.2cm} | p{5cm}| }
\hline
$X$ & $Y$ & Largeur grille & Hauteur grille & Objet\\
\hline
\end{tabular}
\end{center}
\caption{Contenu d'un PayloadTag}
\end{figure}



Voici un exemple d'écriture d'information sur un tag. On constate qu'il y a 2 étapes distinctes:\\
La première consiste à gérer la détection du tag et la récupération de ses coordonnées dans la grille. 
La seconde étape consiste à mettre à jour la valeur du payload contenu dans le tag.\\

\begin{figure}[!ht]
\center \includegraphics[scale=0.35]{RESSOURCES/besoins/diagramme_ecriture.png}
\caption{Interaction lors de l'écriture d'un tag.}
\end{figure}

\FloatBarrier

% gestion backup
Selon la vitesse à laquelle on passe le téléphone sur un tag, il se peut qu'une écriture ne se fasse pas correctement. Un message \texttt{write failed} s'affiche à l'écran. Dans ce cas on garde une sauvegarde de se que l'on voulait écrire et l'utilisateur peut ensuite repasser le téléphone sur le tag afin de réécrire le message prédestiné.


\subsection{Mouvements}
% detection mouvement : stockage en base de données / parler modif manifest
%% décrire mouvement relatifs et absolus
L'objectif étant de faire une table interactive, nous avons du gérer les mouvements. Nous pouvons créer des mouvements qu'il soit relatif ou absolut. Le mouvement absolut étant liée au coordonnées de chaque tags scannés lors du mouvement et le mouvement relatif étant liée à la forme du mouvement, calculé par des vecteurs. Nous pouvons aussi détecter un mouvement lorsque celui-ci sera reproduit.

\paragraph{Sauvegarde de mouvements\\}
Comme nous l'avons décrit dans les fonctionnalités, nous utilisons une base de données pour garder et gérer les mouvements. Pour ce faire nous avons implémenté une classe qui étend \texttt{SQLiteOpenHelper} qui va nous permettre par la suite de gérer notre base de données. 

%\begin{center}
%\begin{tabular}{|l|}
%  \hline
%   \textbf{\texttt{Rules}} \\
%  \hline
%  \texttt{COLUMN\_ID}\\
%  \texttt{COLUMN\_START\_POINT}\\
%  \texttt{COLUMN\_END\_POINT}\\
%  \texttt{COLUMN\_RULES}\\
%  \texttt{COLUMN\_TYPES}\\
%  \hline
%  
%\end{tabular}
%\end{center}

Notre base de données est constitué de la façon suivante :
\begin{itemize}
\item \texttt{COLUMN\_ID} l'identifiant de la colonne
\item \texttt{COLUMN\_START\_POINT} le point de départ du mouvement
\item \texttt{COLUMN\_END\_POINT} le point d'arrivé du mouvement
\item \texttt{COLUMN\_RULES} la rule
\item \texttt{COLUMN\_TYPES} le type de mouvement (absolut ou relatif).
\end{itemize}


Le type \texttt{Rules} contient toutes les informations que l'on a besoin : le nom, le mouvement, l'action associé. 
Pour pouvoir naviguer dans la base, nous avons fait une fonction qui nous renvoi un curseur de \texttt{Rules}. Le curseur est facilement manipulable pour les fonctions de recherche dans la base de données.

%%BDD

\paragraph{Détection de mouvements\\}

Le principe de la détection de mouvement est d'affecter une action à une séquence de tags. Il existe deux façons de réaliser un mouvement : de manière relative ou absolue. Pour réaliser cela, nous comparons le mouvement réalisé avec ceux enregistrés dans la base de données.\\
Plusieurs critères sont pris en compte pour accepter un mouvement de façon fiable :
Pour éviter des tests inutiles, seuls les mouvements de même type sont comparés entre eux. De plus nous testons si les points de départ et d'arrivée du mouvement effectué correspondent avec celui d'un mouvement enregistré. 
Lors de la phase de comparaison entre le mouvement de l'utilisateur et ceux stockés dans la base de données, nous acceptons le fait que l'utilisateur ait pu raté le scan de certains tags. Le nombre de tags consécutifs ratés correspond à une marge d'erreur que nous fixons initialement à 1, mais qui peut être réglable dans les paramètres de l'application.
En fonction du résultat de la comparaison, différents codes d'erreur sont retournés :
\begin{itemize}
\item \texttt{COMPARE\_SUCCESS} en cas de réussite de la comparaison
\item \texttt{COMPARE\_FAIL} si les mouvements ne sont pas de même type
\item \texttt{COMPARE\_TOO\_LONG\_JUMP} si un trop grand nombre de tags ne coïncident pas
\end{itemize}
Pour chaque type de mouvement nous avons un algorithme différent qui est utilisé :
Lors de la comparaison de deux mouvements relatifs, nous calculons le vecteur mouvement correspondant au premier tag de la séquence avec le tag courant pour chacun d'eux. Nous comparons ensuite les vecteurs deux à deux.
%%INSERER PSEUDO CODE DE FONCTION ?
Dans le cas des mouvements absolus, nous comparons point à point les positions des tags scannés.

\begin{figure}[!ht]
\center \includegraphics[scale=0.35]{RESSOURCES/besoins/diagrammeBDD.png}
\caption{Interaction lors de l'écriture d'un tag.}
\end{figure}

\subsection{Bluetooth}

\paragraph{Introduction :} Dans cette section, nous allons voir comment nous avons intéragi avec l'adaptateur Bluetooth local et la façon avec laquelle nous avons réussi à communiquer avec des terminaux distants.

Comme nous l'avons vu précédemment, le Bluetooth est un protocole de communication conçu pour des communications peer-to-peer (appareil à appareil) à courtes distances. Sous Android 2.1, seules les communications cryptées sont supportées, ce qui signifie que nous ne pouvons nous connecter qu'avec des périphériques préalablement appariés.

Les périphériques et connexions Bluetooth sont gérés par les classes suivantes:
\begin{itemize}
\item \textit{BluetoothAdapter} : Cette classe représente l'adaptateur local, c'est à dire l'appareil Android où l'application est exécutée.
\item \textit{BluetoothDevice} : Représente chaque périphérique distant avec lequel nous voulons communiquer.
\item \textit{BluetoothSocket} : Cette classe nous permet d'effectuer une demande de connexion vers le périphérique distant puis d'initier la communication.
\item \textit{BluetoothServerSocket} : Cette classe nous permet d'écouter les demandes de connexion provenant des \textit{BluetoothSocket} des périphériques distants.
\end{itemize}

\paragraph{Information :} Les bibliothèques Bluetooth ne sont disponibles que pour les versions supérieures à 2.0 (SDK API level 5). Bien que le protocole Bluetooth supporte les connexions en mode Ad-Hoc, ce mécanisme n'est pas actuellement disponible sous Android.

\FloatBarrier   % force notamment les flottants précédents à ne pas dépasser cette limite 
\begin{figure}[h!]
  \centering
  \includegraphics[width=270px]{RESSOURCES/bluetooth.jpeg}
\caption{Diagramme de la pile Bluetooth Android\protect\footnotemark}        
\end{figure}
\footnotetext{\url{http://source.android.com/porting/bluetooth.html}}
\FloatBarrier   % force notamment les flottants précédents à ne pas dépasser cette limite 

\paragraph{Connexion et communications :}  Les API de communication Bluetooth sont des "wrappers" autour de RFCOMM, le protocole de communication à radio fréquence Bluetooth. 

Comme nous l'avons vu précédemment, nous pouvons établir une communication bidirectionnelles en utilisant les classes \textit{BluetoothSocket} et \textit{BluetoothServerSocket}. Nous devons donc implémenter à la fois un socket serveur écoutant les demandes de connexion et un socket client pour initier un nouveau canal et gérer les communications. Notre application est donc à la fois client et serveur. 
Une fois connecté, le socket serveur utilise un socket Bluetooth pour envoyer et recevoir des données. Une fois la connexion établie, les notions de serveur et de client ne sont plus significatives car ce socket Bluetooth s'utilise de la même manière de chaque coté.

Pour écouter les connexions entrantes, nous utilisons la méthode \textit{listenUsingRfcomWithServiceRecord} du \textit{BluetoothAdapter} prenant comme paramètre un nom et un UUID (identifiant universel que nous utilisons aussi pour simuler la notion de canal). Cette méthode nous renvoie un \textit{BluetoothServerSocket}. Pour attendre les demandes de connexions, nous utilisons la méthode \textit{accept}. Le thread serveur se bloque donc jusqu'à ce qu'un client possédant le même UUID tente de se connecter. Si la connexion réussi, \textit{accept()} renverra un socket connecté au client que nous pouvons utiliser pour transférer des données. Ce mécanisme est géré par un thread qui tourne en permanence en arrière plan.

Pour ouvrir une connexion, nous utilisons la liste des adresses physiques des périphé\-riques appariés. On récupère donc une liste de \textit{BluetoothDevice} qui vont nous permettre de faire appel à la méthode \textit{createRfcommSocketToServiceRecord} avec pour paramètre l'UUID adéquat. Le \textit{BluetoothSocket} renvoyé nous permet donc d'initier la connexion à l'aide de la méthode \textit{connect()}. Une fois la méthode \textit{connect()} terminée, on peut se servir du \textit{BluetoothSocket} pour transférer les données.

Les transferts de données entre sockets sont gérés par les objets Java standard \textit{InputStream} et \textit{OutputStream}.

Enfin pour monitorer l'état du Bluetooth, nous utilisons la classe
\textit{BroadcastReceiver} qui récupère les informations envoyées par le
système.\\


\lstset{title=Récupération des informations lors d'un changement d'état de la connexion Bluetooth}
\begin{lstlisting}[frame=trBL]
  	private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
		public void onReceive(Context context, Intent intent) {
			String action = intent.getAction();
			if (BluetoothDevice.ACTION_FOUND.equals(action)) {
				BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
				if (device.getBondState() != BluetoothDevice.BOND_BONDED) {
					detectedAddr.add(device.getAddress());
					detectedName.add(device.getName());
				}
			} else if (BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action)) {
				mHandler.sendEmptyMessage(MSG_END);
				rec.setAdapter(detectedName);
			}}};
\end{lstlisting}

\FloatBarrier   % force notamment les flottants précédents à ne pas dépasser cette limite 





\subsection{Multilangues}

L'API Android nous offre la possibilité de pouvoir adapter la langue de notre application, à la langue paramétrée dans le téléphonne.\\
Le principe est le suivant: Par défaut, chaque chaine de caractères est
déclarée, et initialisée dans le dossier \textit{res/values/} (Par
soucis de clarté, nous avons découpé le fichier \textit{string.xml}, un par interface graphique).\\
Pour que la langue de l'application s'adapte au téléphone, il faut
traduire toutes les valeurs des variables contenues dans les différents
fichiers  de \textit{res/values/} pour les mettre dans \textit{res/values-xx/} , où \textit{xx} représente l'identifiant de la langue souhaitée. \\

Nous avons donc traduit notre application en Anglais et en Français. Ce qui nous donne la structure suivante:
\begin{itemize}
\item[\ding{219}]  \textit{res/values/strings.xml} qui est la valeur par défaut si la langue n'est pas disponible.
\item[\ding{219}]  \textit{res/values-fr/strings.xml} pour la version française.\\
\end{itemize}

Il est donc très simple et rapide d'ajouter une nouvelle langue.\\
Nous avons aussi rajouté un champ dans les paramètres permettant de
sélectionner la langue de son choix. 
